package com.yourenbang.lingyun.transaction.web.service.impl.fund;

import com.yourenbang.lingyun.constants.BizCodeMessages;
import com.yourenbang.lingyun.constants.Constant;
import com.yourenbang.lingyun.constants.DeleteFlag;
import com.yourenbang.lingyun.constants.enums.ChannelIdEnums;
import com.yourenbang.lingyun.constants.enums.FundBillType;
import com.yourenbang.lingyun.constants.enums.PlatNoEnums;
import com.yourenbang.lingyun.constants.enums.fund.AccountMainJournalType;
import com.yourenbang.lingyun.constants.enums.fund.AccountType;
import com.yourenbang.lingyun.constants.enums.pay.OrderNoPrefixEnum;
import com.yourenbang.lingyun.constants.enums.table.AllyActivateHierarchyEnum;
import com.yourenbang.lingyun.constants.enums.table.FundWithdrawDebitListEnum;
import com.yourenbang.lingyun.constants.enums.table.SubTeamBeanEnum;
import com.yourenbang.lingyun.core.config.datasource.DataSources;
import com.yourenbang.lingyun.core.config.datasource.RoutingDataSource;
import com.yourenbang.lingyun.core.exception.BizRuntimeException;
import com.yourenbang.lingyun.core.exception.SysBizException;
import com.yourenbang.lingyun.core.message.Result;
import com.yourenbang.lingyun.core.model.vo.PageVO;
import com.yourenbang.lingyun.core.support.PageFrom;
import com.yourenbang.lingyun.core.util.ClientUtils;
import com.yourenbang.lingyun.core.util.ExportExcelUtils;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.StringUtil;
import com.yourenbang.lingyun.core.util.date.DateFormat;
import com.yourenbang.lingyun.core.util.date.LocalDateUtils;
import com.yourenbang.lingyun.domain.*;
import com.yourenbang.lingyun.mapper.*;
import com.yourenbang.lingyun.openapi.api.model.dto.client.ClientInfo;
import com.yourenbang.lingyun.openapi.api.service.client.ClientService;
import com.yourenbang.lingyun.transaction.constant.ChangeTypeConstant;
import com.yourenbang.lingyun.transaction.mapper.*;
import com.yourenbang.lingyun.transaction.util.CommonUtils;
import com.yourenbang.lingyun.transaction.util.DateUtil;
import com.yourenbang.lingyun.transaction.util.DateUtils;
import com.yourenbang.lingyun.transaction.web.domain.dto.ChangeFundAccountV2DTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.fund.ManageChangeFundDTO;
import com.yourenbang.lingyun.transaction.web.domain.dto.manage.*;
import com.yourenbang.lingyun.transaction.web.domain.po.Merchant;
import com.yourenbang.lingyun.transaction.web.domain.vo.JournalInfoVO;
import com.yourenbang.lingyun.transaction.web.domain.vo.manage.ManageActivateRewardVO;
import com.yourenbang.lingyun.transaction.web.domain.vo.manage.ManageFundBillVO;
import com.yourenbang.lingyun.transaction.web.domain.vo.manage.ManageUserFundAccountVO;
import com.yourenbang.lingyun.transaction.web.domain.vo.manage.ManageWithdrawalDebitListVO;
import com.yourenbang.lingyun.transaction.web.service.CommonService;
import com.yourenbang.lingyun.transaction.web.service.fund.FundService;
import com.yourenbang.lingyun.transaction.web.service.impl.pay.withdraw.WithdrawAccountConfig;
import com.yourenbang.lingyun.transaction.web.service.manage.ManageFundService;
import com.yourenbang.merchant.api.model.dto.CheckActiveRewardYxyDTO;
import com.yourenbang.merchant.api.service.MerchantRewardApiService;
import com.yourenbang.merchant.api.service.yxy.MerchantYxyRewardApiService;
import com.yourenbang.transaction.api.model.vo.manage.QueryPledgeListVO;
import com.yourenbang.transaction.api.model.vo.pay.PayTransaction;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.yourenbang.lingyun.transaction.web.service.impl.pay.transaction.PayTransactionConfig.getTransTableIndex;

/**
 * @Description
 * @Date 2020/12/4 9:36
 * @Created by Jason
 */
@Service
@Slf4j
public class ManageFundServiceImpl implements ManageFundService {
    @Resource
    private TransactionFundBillMapper transactionFundBillMapper;
    @Resource
    private TransactionFundAccountMapper transactionFundAccountMapper;
    @Resource
    private TransactionAllyActivateRewardMapper transactionAllyActivateRewardMapper;
    @Resource
    private FundAccountMapper fundAccountMapper;
    @Resource
    private UserBaseMapper userBaseMapper;
    @Resource
    private CommonService commonService;
    @Resource
    private AllyActivateHierarchy21Mapper allyActivateHierarchy21Mapper;
    @Resource
    private TransactionPayTransactionMapper payTransactionMapper;
    @Resource
    private MerchantYxyRewardApiService merchantYxyRewardApiService;
    @Resource
    private MeMerchantLinkUser21Mapper meMerchantLinkUser21Mapper;
    @Resource
    private MerchantRewardApiService merchantRewardApiService;
    @Resource
    private FundWithdrawDebitListMapper fundWithdrawDebitListMapper;
    @Resource
    private TransactionFundWithdrawDebitListMapper transactionFundWithdrawDebitListMapper;
    @Resource
    private AllyAwardBillMapper allyAwardBillMapper;
    @Resource
    private UserMerchantRecommend20Mapper userMerchantRecommend20Mapper;
    @Resource
    private AllyMapper allyMapper;
    @Autowired
    ClientService clientService;
    @Autowired
    FundService fundService;

    @Override
    @RoutingDataSource(DataSources.SLAVE_DB)
    public Result<PageVO> queryFundBill(ManageFundBillDTO dto) {

        //ID为空则返回空列表
        if (Objects.isNull(dto.getFundAccountId())) {
            return Result.builder().successPage(Lists.newArrayList());
        }

        FundAccount fundAccount = fundAccountMapper.selectByPrimaryKey(dto.getFundAccountId());
        List<Integer> accountIdList = Collections.singletonList(dto.getFundAccountId());
        dto.setAccountIdList(accountIdList);
        dto.setPlatNo(fundAccount.getPlatNo());
        PageFrom.startPage(dto.getPageNum(), dto.getPageSize());
        dto.setCreateTimeEnd(LocalDateUtils.formatByDefaultFormat(LocalDateUtils.parseLocalDateByDefaultFormat(dto.getCreateTimeEnd()).plusDays(1)));
        List<ManageFundBillVO> fundBillManageVOS = transactionFundBillMapper.queryFundBill(dto);
        fundBillManageVOS.forEach(item -> {
            if(item.getType() == 777) {
                item.setTypeName("账户冻结");
            } else if(item.getType() == 778) {
                item.setTypeName("账户解冻");
            } else {
                item.setTypeName(FundBillType.getUserBillType(item.getType()).getName());
            }
            if (FundBillType.TYPE_110.isEquals(item.getType()) || FundBillType.TYPE_113.isEquals(item.getType()) || FundBillType.TYPE_460.isEquals(item.getType())) {
                String[] orderIds = StringUtils.split(item.getOrderId(), "-");
                if (orderIds.length > 2) {
                    String userBaseId = orderIds[0];
                    Short channelId = Short.parseShort(orderIds[PlatNoEnums.YXY.isEquals(dto.getPlatNo()) ? 1 : 2]);
                    Merchant merchant = meMerchantLinkUser21Mapper.getMerchantByPlatNo(userBaseId, channelId, dto.getPlatNo());
                    if (Objects.nonNull(merchant)) {
                        item.setFromUser(merchant.getMerchantNo());
                    }
                }
            }
        });
        Result<PageVO> pageVOResult = Result.builder().successPage(fundBillManageVOS);
        return pageVOResult;
    }

    @Override
    @RoutingDataSource(DataSources.SLAVE_DB)
    public Result<PageVO> queryFundBillAllowance(ManageFundBillDTO dto) {

        dto.setPlatNo(PlatNoEnums.YXY.getCode());
        dto.setType(FundBillType.getFundBillType(SubTeamBeanEnum.AwardTypeEnum.getAwardType(dto.getType())).getType());
        PageFrom.startPage(dto.getPageNum(), dto.getPageSize());
        List<ManageFundBillVO> fundBillManageVOS = transactionFundBillMapper.queryFundBillAllowance(dto);
        fundBillManageVOS.forEach(item -> item.setTypeName(FundBillType.getUserBillType(item.getType()).getName()));
        Result<PageVO> pageVOResult = Result.builder().successPage(fundBillManageVOS);
        return pageVOResult;
    }

    @Override
    @RoutingDataSource(DataSources.SLAVE_DB)
    public Result<PageVO> queryUserAccountList(ManageUserAccountDTO dto) {
        //用户存在性判断
        UserBaseExample userBaseExample = new UserBaseExample();
        UserBaseExample.Criteria criteria = userBaseExample.createCriteria();
        criteria.andIsDelEqualTo(Constant.NO).andPlatNoEqualTo(Short.valueOf(dto.getPlatNo()));

        if (StringUtils.isNotEmpty(dto.getPhone())) {
            criteria.andPhoneEqualTo(dto.getPhone());
        }
        if (StringUtils.isNotEmpty(dto.getReferralCode())) {
            criteria.andReferralCodeEqualTo(dto.getReferralCode());
        }

        List<UserBase> userBaseList = userBaseMapper.selectByExample(userBaseExample);
        if (userBaseList.isEmpty()) {
            return Result.builder().successPage(Lists.newArrayList());
        }

        List<Integer> accountTypeList = Lists.newArrayList();
        AccountType one = AccountType.getAccountTypeByFullCode(1);

        //获取所有的账户类型
        accountTypeList.add(Integer.valueOf(AccountType.MERCHANT_FROM_BOSS.getShortAccountNo()));
        accountTypeList.add(Integer.valueOf(AccountType.MER.getShortAccountNo()));
        accountTypeList.add(Integer.valueOf(AccountType.ALLY_V2.getShortAccountNo()));
        accountTypeList.add(Integer.valueOf(AccountType.ALLY_FROM_BOSS.getShortAccountNo()));
        //accountTypeList.add(100777);

        //查询账户列表
        PageFrom.startPage(dto.getPageNum(), dto.getPageSize());
        List<ManageUserFundAccountVO> accountVOList = transactionFundAccountMapper.selectUserFundAccountList(
                userBaseList.size() == 1 ? userBaseList.get(0).getUserBaseId() : null,
                accountTypeList.stream().map(accountType -> dto.getPlatNo() + accountType).collect(Collectors.toList()),
                dto.getA9UserBaseId());
        if (PlatNoEnums.YXY.getCode().equals(Short.valueOf(dto.getPlatNo())) && CollectionUtils.isNotEmpty(accountVOList)) {
            accountVOList.forEach(item -> item.setChange(AccountType.getFullCode(AccountType.ALLY_V2, PlatNoEnums.YXY.getCode()).equals(item.getAccountType())
                    || AccountType.getFullCode(AccountType.MER, PlatNoEnums.YXY.getCode()).equals(item.getAccountType())));
        }
        return Result.builder().successPage(accountVOList);
    }

    @Override
    @SuppressWarnings("unchecked")
    public void exportUserAccount(ManageUserAccountExportDTO dto) {
        dto.setPageNum(1);
        dto.setPageSize(100000);
        if ("10".equals(dto.getExportType())) { // 10账户明细
            Result<PageVO> pageVOResult = queryUserAccountList(dto);
            List<ManageUserFundAccountVO> queryPledgeListVOS = (List<ManageUserFundAccountVO>) pageVOResult.getData().getList();
            queryPledgeListVOS.forEach(item -> {
                item.setAccountName(CommonUtils.getAccountNameByAccountType(item.getAccountType()));
                item.setPlatNoName(PlatNoEnums.getPlatNo(item.getPlatNo()).getName());
            });
            String title = "账户明细导出-" + DateFormat.DATETIME_COMPACT.format(LocalDateTime.now());

            String[] headers = {"姓名", "手机号", "推荐码", "总收入金额", "可提金额", "已提金额", "冻结中金额", "不可提金额", "账户类型", "平台", "创建时间"};
            String[] fieldNames = {"userName", "phone", "referralCode", "accountIncome", "accountAmountWithdrawable",
                    "accountAmountWithdrawed", "accountAmountFrozen", "accountAmountUndepositable", "accountName", "platNoName", "createTime"};
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

            HttpServletRequest request = servletRequestAttributes.getRequest();
            HttpServletResponse response = servletRequestAttributes.getResponse();
            ExportExcelUtils.exportExcel(title, headers, fieldNames, queryPledgeListVOS, request, response);
        } else if ("20".equals(dto.getExportType())) { // 20账户收入明细
            //用户存在性判断
            UserBaseExample userBaseExample = new UserBaseExample();
            UserBaseExample.Criteria criteria = userBaseExample.createCriteria();
            criteria.andIsDelEqualTo(Constant.NO).andPlatNoEqualTo(Short.valueOf(dto.getPlatNo()));
            if (StringUtils.isNotEmpty(dto.getPhone())) {
                criteria.andPhoneEqualTo(dto.getPhone());
            }
            if (StringUtils.isNotEmpty(dto.getReferralCode())) {
                criteria.andReferralCodeEqualTo(dto.getReferralCode());
            }
            List<UserBase> userBaseList = userBaseMapper.selectByExample(userBaseExample);
            //获取所有的账户类型
            List<AccountType> accountTypeList = Arrays.asList(AccountType.MERCHANT_FROM_BOSS, AccountType.MER, AccountType.ALLY_V2, AccountType.ALLY_FROM_BOSS);
            //查询账户列表
            List<ManageUserFundAccountVO> accountVOList = null;
            if (userBaseList.size() == 1) {
                accountVOList = transactionFundAccountMapper.selectUserFundAccountList(
                        userBaseList.get(0).getUserBaseId(),
                        accountTypeList.stream().map(accountType -> dto.getPlatNo() + accountType.getShortAccountNo()).collect(Collectors.toList()),
                        dto.getA9UserBaseId());
            }
            List<Integer> fundAccountIds=new ArrayList<>();
            if (CollectionUtils.isNotEmpty(accountVOList)) {
                fundAccountIds=accountVOList.stream().map(ManageUserFundAccountVO::getFundAccountId).collect(Collectors.toList());
            }
            ManageFundBillDTO fundBillDTO = new ManageFundBillDTO();
            fundBillDTO.setPlatNo(PlatNoEnums.YXY.getCode());
            fundBillDTO.setAccountIdList(fundAccountIds);

            String createBeginTime = dto.getExportDetailMonth() + "-01 00:00:00";
            fundBillDTO.setCreateTimeBegin(createBeginTime);

            String createEndTime = LocalDateTime.parse(createBeginTime, DateTimeFormatter.ofPattern(DateUtil.parsePatterns[1]))
                    .plusMonths(1L).format(DateTimeFormatter.ofPattern(DateUtil.parsePatterns[1]));
            fundBillDTO.setCreateTimeEnd(createEndTime);
            List<ManageFundBillVO> fundBillManageVOS = transactionFundBillMapper.queryFundBill(fundBillDTO);
            if (CollectionUtils.isNotEmpty(fundBillManageVOS)) {
                fundBillManageVOS.forEach(item -> {
                    item.setTypeName(FundBillType.getUserBillType(item.getType()).getName());
                });
            }
            String title = "账户出入明细导出-" + DateFormat.DATETIME_COMPACT.format(LocalDateTime.now());

            String[] headers = {"姓名", "手机号", "推荐码", "账户类型", "订单号", "变动金额", "变动后余额","创建时间", "变动类型", "备注", "操作人"};
            String[] fieldNames = {"userName", "phone", "referralCode", "accountName", "orderId", "changeAmount", "leftAmount", "createTime", "typeName", "detail", "operator"};
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

            HttpServletRequest request = servletRequestAttributes.getRequest();
            HttpServletResponse response = servletRequestAttributes.getResponse();
            ExportExcelUtils.exportExcel(title, headers, fieldNames, fundBillManageVOS, request, response);
        }
    }

    @Override
    @RoutingDataSource(DataSources.SLAVE_DB)
    public Result<PageVO<ManageActivateRewardVO>> queryRewardList(ManageAllyActivateRewardDTO dto) {

        PageFrom.startPage(dto.getPageNum(), dto.getPageSize());
        List<ManageActivateRewardVO> manageActivateRewardVOS = null;
        if (PlatNoEnums.YXY.isEquals(dto.getPlatNo())) {
            manageActivateRewardVOS = transactionAllyActivateRewardMapper.queryActivateRewardYxy(dto);
            //临时记录1阶段的返现状态，用于判断未注册
            String activeUserBaseId = "";
            short activeStatus = 0;
            //虚拟商户获取真实姓名、手机号
            for (ManageActivateRewardVO manageActivateRewardVO : manageActivateRewardVOS) {
                manageActivateRewardVO.setTerminalType(ChannelIdEnums.getChannelIdEnums(manageActivateRewardVO.getChannelId()).getMsg());
                if (StringUtil.startsWith(manageActivateRewardVO.getFromUserPhone(), "v_")) {
                    if (StringUtil.isNotEmpty(manageActivateRewardVO.getLinkPhone())) {
                        manageActivateRewardVO.setFromUserPhone(manageActivateRewardVO.getLinkPhone());
                    } else {
                        manageActivateRewardVO.setFromUserPhone("");
                    }
                    if (StringUtil.isNotEmpty(manageActivateRewardVO.getLinkUserName())) {
                        manageActivateRewardVO.setFromUserPhone(manageActivateRewardVO.getLinkUserName());
                    } else {
                        manageActivateRewardVO.setFromUserPhone("");
                    }
                }
                if (!AllyActivateHierarchyEnum.PaymentStatusEnum.STATUS_10.isEquals(manageActivateRewardVO.getPaymentStatus())) {
                    manageActivateRewardVO.setRewardTime(manageActivateRewardVO.getPaymentTime());
                }
                if (StringUtil.equals(manageActivateRewardVO.getHierarchy(), AllyActivateHierarchyEnum.StageEnum.STAGE_FIRST.getCode().toString())) {
                    activeUserBaseId = manageActivateRewardVO.getFromUserBaseId();
                    activeStatus = manageActivateRewardVO.getStatus();
                    if (AllyActivateHierarchyEnum.PaymentStatusEnum.STATUS_20.isEquals(manageActivateRewardVO.getPaymentStatus())) {
                        activeStatus = ManageActivateRewardVO.UN_REGISTER_STATUS;
                        manageActivateRewardVO.setStatus(activeStatus);
                    }
                } else { //如果一阶段是未注册，那么二酸阶段也是未注册
                    if (StringUtil.equals(activeUserBaseId, manageActivateRewardVO.getFromUserBaseId())
                            && ManageActivateRewardVO.UN_REGISTER_STATUS.equals(activeStatus)) {
                        manageActivateRewardVO.setStatus(activeStatus);
                    }
                }
            }
        } else {
            if (StringUtils.isNotBlank(dto.getA9UserBaseId())) {
                return Result.builder().successPageT(manageActivateRewardVOS);
            }
            manageActivateRewardVOS = transactionAllyActivateRewardMapper.queryActivateReward(dto);

            if (CollectionUtils.isEmpty(manageActivateRewardVOS)) {
                return Result.builder().successPageT(manageActivateRewardVOS);
            }

        }
        manageActivateRewardVOS.forEach(manageActivateRewardVO -> manageActivateRewardVO.setChannelIdName(
                ChannelIdEnums.getChannelNameByCode(manageActivateRewardVO.getChannelId())));
        //重新分页
        Result<PageVO<ManageActivateRewardVO>> result = Result.builder().successPageT(manageActivateRewardVOS);
        long total = result.getData().getTotal();
        long pages = ((total - 1) / dto.getPageSize()) + 1;
        result.getData().setPages((int) pages);
        result.getData().setTotal(total);
        result.getData().setPageSize(manageActivateRewardVOS.size());
        return result;
    }

    @Override
    public Result resetActivateReward(ManageResetActivateRewardDTO dto) {

        if (!PlatNoEnums.YXY.getCode().equals(dto.getPlatNo())) {
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "暂不支持该平台");
        }

        AllyActivateHierarchy21Example example = new AllyActivateHierarchy21Example();
        example.createCriteria().andPlatNoEqualTo(dto.getPlatNo()).andChannelIdEqualTo(dto.getChannelId())
                .andFromUserBaseIdEqualTo(dto.getFromUserBaseId()).andToUserBaseIdEqualTo(dto.getToUserBaseId());
        List<AllyActivateHierarchy21> allyActivateHierarchy21List
                = allyActivateHierarchy21Mapper.selectByExample(example);

        if (CollectionUtils.isEmpty(allyActivateHierarchy21List)) {
            KLog.error("未找到激活返现数据,入参：{}", dto.toJSON());
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "未找到激活返现数据");
        }

        allyActivateHierarchy21List.forEach(allyActivateHierarchy21 -> {
            if (AllyActivateHierarchyEnum.StatusEnum.STATUS_30.getCode().equals(allyActivateHierarchy21.getStatus())) {
                AllyActivateHierarchy21 allyActivateHierarchy = new AllyActivateHierarchy21();
                allyActivateHierarchy.setAllyActivateHierarchyId(allyActivateHierarchy21.getAllyActivateHierarchyId());
                allyActivateHierarchy.setStatus(AllyActivateHierarchyEnum.StatusEnum.STATUS_10.getCode());
                allyActivateHierarchy21Mapper.updateByPrimaryKeySelective(allyActivateHierarchy);
            }
        });


        PayTransaction payTransaction = payTransactionMapper.selectYxyPledgeAmount(dto.getFromUserBaseId(),
                getTransTableIndex(dto.getFromUserBaseId()), dto.getChannelId());

        //P42首笔交易
        if (ChannelIdEnums.yxy_lkl_p42.getCode().equals(dto.getChannelId())) {
            payTransaction = payTransactionMapper.selectYxyP42PledgePayTransaction(dto.getFromUserBaseId(),
                    getTransTableIndex(dto.getFromUserBaseId()));
        }

        if (ChannelIdEnums.yxy_jl_m40.getCode().equals(dto.getChannelId())) {
            payTransaction = new PayTransaction();
            payTransaction.setUserBaseId(dto.getFromUserBaseId());
            payTransaction.setTransactionTime(LocalDateTime.now());
        }

        if (Objects.isNull(payTransaction)) {

            KLog.error("未找到交易数据,入参：{}", dto.toJSON());
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "未找到交易数据");
        }

        CheckActiveRewardYxyDTO checkActiveRewardYxyDTO = new CheckActiveRewardYxyDTO();
        checkActiveRewardYxyDTO.setChannelId(dto.getChannelId());
        checkActiveRewardYxyDTO.setPlatNo(dto.getPlatNo());
        checkActiveRewardYxyDTO.setUserBaseId(payTransaction.getUserBaseId());
        checkActiveRewardYxyDTO.setTradeAmount(payTransaction.getTransactionAmount());
        checkActiveRewardYxyDTO.setTradeTime(payTransaction.getTransactionTime());

        KLog.info("请求检查激活返现rpc,入参:{}", checkActiveRewardYxyDTO.toJSON());

        Result<Void> checkYxyReward;
        if (ChannelIdEnums.yxy_jl_m40.getCode().equals(dto.getChannelId())) {
            checkYxyReward = merchantRewardApiService.checkRewardYxy(checkActiveRewardYxyDTO);
        } else {
            checkYxyReward = merchantYxyRewardApiService.checkYxyReward(checkActiveRewardYxyDTO);
        }

        if (!checkYxyReward.isSuccess()) {
            KLog.error("请求检查激活返现rpc未成功:{},入参:{}", checkYxyReward.getDesc(), checkActiveRewardYxyDTO.toJSON());
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "请求检查激活返现rpc未成功");
        }

        return Result.builder().success("重置成功");
    }

    @Override
    public Result invalidActivateReward(ManageResetActivateRewardDTO dto) {

        AllyActivateHierarchy21Example example = new AllyActivateHierarchy21Example();
        example.createCriteria().andPlatNoEqualTo(dto.getPlatNo()).andChannelIdEqualTo(dto.getChannelId())
                .andFromUserBaseIdEqualTo(dto.getFromUserBaseId()).andToUserBaseIdEqualTo(dto.getToUserBaseId());
        List<AllyActivateHierarchy21> allyActivateHierarchy21List
                = allyActivateHierarchy21Mapper.selectByExample(example);

        if (CollectionUtils.isEmpty(allyActivateHierarchy21List)) {
            KLog.error("未找到激活返现数据,入参：{}", dto.toJSON());
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "未找到激活返现数据");
        }

        allyActivateHierarchy21List.forEach(allyActivateHierarchy21 -> {
            if (AllyActivateHierarchyEnum.StatusEnum.STATUS_10.getCode().equals(allyActivateHierarchy21.getStatus())) {
                AllyActivateHierarchy21 allyActivateHierarchy = new AllyActivateHierarchy21();
                allyActivateHierarchy.setAllyActivateHierarchyId(allyActivateHierarchy21.getAllyActivateHierarchyId());
                allyActivateHierarchy.setStatus(AllyActivateHierarchyEnum.StatusEnum.STATUS_30.getCode());
                allyActivateHierarchy21Mapper.updateByPrimaryKeySelective(allyActivateHierarchy);
            }
        });

        return Result.builder().success("作废成功");
    }

    @Override
    public Result delActivateReward(ManageResetActivateRewardDTO dto) {
        AllyActivateHierarchy21Example example = new AllyActivateHierarchy21Example();
        example.createCriteria().andPlatNoEqualTo(dto.getPlatNo()).andChannelIdEqualTo(dto.getChannelId())
                .andFromUserBaseIdEqualTo(dto.getFromUserBaseId()).andToUserBaseIdEqualTo(dto.getToUserBaseId());
        List<AllyActivateHierarchy21> allyActivateHierarchy21List
                = allyActivateHierarchy21Mapper.selectByExample(example);

        if (CollectionUtils.isEmpty(allyActivateHierarchy21List)) {
            KLog.error("未找到激活返现数据,入参：{}", dto.toJSON());
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "未找到激活返现数据");
        }

        allyActivateHierarchy21List.forEach(allyActivateHierarchy21 -> {
            AllyActivateHierarchy21 allyActivateHierarchy = new AllyActivateHierarchy21();
            allyActivateHierarchy.setAllyActivateHierarchyId(allyActivateHierarchy21.getAllyActivateHierarchyId());
            allyActivateHierarchy.setStatus(AllyActivateHierarchyEnum.StatusEnum.STATUS_30.getCode());
            allyActivateHierarchy.setIsDel(Constant.YES);
            allyActivateHierarchy.setTerminalSn(allyActivateHierarchy21List.get(0).getTerminalSn()+"-del");
            allyActivateHierarchy.setFromUserBaseId(allyActivateHierarchy21List.get(0).getFromUserBaseId()+"-del");
            allyActivateHierarchy21Mapper.updateByPrimaryKeySelective(allyActivateHierarchy);
        });

        return Result.builder().success();
    }

    @Override
    public Result manageAddFund(ManageChangeFundDTO manageChangeFundDTO) {

        if (commonService.repeatSubmit(manageChangeFundDTO.getUserPhone() + ":manageAddFund")) {
            return Result.builder().fail(BizCodeMessages.VALIDATOR_REPEAT_SUBMIT);
        }
        Result result;

        UserBaseExample userBaseExample = new UserBaseExample();
        userBaseExample.createCriteria().andPlatNoEqualTo(manageChangeFundDTO.getPlatNo())
                .andPhoneEqualTo(manageChangeFundDTO.getUserPhone());
        List<UserBase> userBases = userBaseMapper.selectByExample(userBaseExample);
        if (CollectionUtils.isEmpty(userBases)) {
            return Result.builder().fail(BizCodeMessages.PARAMETER_ERR, "用户不存在");
        }

        Short platNo = new Short(StringUtils.left(manageChangeFundDTO.getAccountType().toString(), 2));

        AccountType toAccountType = AccountType.getAccountTypeByFullCode(manageChangeFundDTO.getAccountType());
        AccountMainJournalType accountMainJournalType = AccountMainJournalType.getMainJournalTypeByCode(manageChangeFundDTO.getAccountMainJournalType());

        JournalInfoVO journalVO = ChangeTypeConstant.getAddJournalTypeV2(toAccountType, accountMainJournalType);

        FundBillType fundBillType = FundBillType.getUserBillType(manageChangeFundDTO.getBillType());
        String orderNo = WithdrawAccountConfig.genOrderNo(OrderNoPrefixEnum.MANAGE_ADD.getCode());

        ChangeFundAccountV2DTO changeFundAccountV2DTO = new ChangeFundAccountV2DTO();
        changeFundAccountV2DTO.setUserBaseId(userBases.get(0).getUserBaseId());
        changeFundAccountV2DTO.setFundBillType(fundBillType);
        changeFundAccountV2DTO.setChangeAmount(manageChangeFundDTO.getChangeAmount());
        changeFundAccountV2DTO.setChannelId(ChannelIdEnums.no.getCode());
        changeFundAccountV2DTO.setPlatNo(platNo);
        changeFundAccountV2DTO.setDetail(manageChangeFundDTO.getDetail());
        changeFundAccountV2DTO.setJournalInfo(journalVO);
        changeFundAccountV2DTO.setOperator(manageChangeFundDTO.getOperator());
        changeFundAccountV2DTO.setManualFlag(true);
        changeFundAccountV2DTO.setOrderNo(orderNo);

        result = fundService.add(changeFundAccountV2DTO);


        if (!result.isSuccess()) {
            result.setDesc("加账失败,暂时不要重复加账,询问负责人是否有重试机制");
        }
        return result;

    }

    @Override
    public Result manageSubtractFund(ManageChangeFundDTO manageChangeFundDTO) {

        if (commonService.repeatSubmit(manageChangeFundDTO.getUserPhone() + ":manageSubtractFund")) {
            return Result.builder().fail(BizCodeMessages.CORE_API_REQUEST_LIMITED);
        }

        Result result = null;

        UserBaseExample userBaseExample = new UserBaseExample();
        userBaseExample.createCriteria().andPlatNoEqualTo(manageChangeFundDTO.getPlatNo()).andPhoneEqualTo(manageChangeFundDTO.getUserPhone());
        List<UserBase> userBases = userBaseMapper.selectByExample(userBaseExample);
        if (CollectionUtils.isEmpty(userBases)) {
            return Result.builder().fail(BizCodeMessages.PARAMETER_ERR, "用户不存在");
        }


        LocalDateTime now = LocalDateTime.now();
        Short platNo = new Short(StringUtils.left(manageChangeFundDTO.getAccountType().toString(), 2));

        AccountType toAccountType = AccountType.getAccountTypeByFullCode(manageChangeFundDTO.getAccountType());
        AccountMainJournalType accountMainJournalType = AccountMainJournalType.getMainJournalTypeByCode(manageChangeFundDTO.getAccountMainJournalType());

        JournalInfoVO journalVO = ChangeTypeConstant.getSubtractJournalTypeV2(toAccountType,
                accountMainJournalType);

        FundBillType fundBillType = FundBillType.getUserBillType(manageChangeFundDTO.getBillType());
        String orderNo = WithdrawAccountConfig.genOrderNo(OrderNoPrefixEnum.MANAGE_REVERSAL.getCode());

        ChangeFundAccountV2DTO changeFundAccountV2DTO = new ChangeFundAccountV2DTO();
        changeFundAccountV2DTO.setUserBaseId(userBases.get(0).getUserBaseId());
        changeFundAccountV2DTO.setFundBillType(fundBillType);
        changeFundAccountV2DTO.setChangeAmount(manageChangeFundDTO.getChangeAmount());
        changeFundAccountV2DTO.setChannelId(ChannelIdEnums.no.getCode());
        changeFundAccountV2DTO.setPlatNo(platNo);
        changeFundAccountV2DTO.setDetail(manageChangeFundDTO.getDetail());
        changeFundAccountV2DTO.setJournalInfo(journalVO);
        changeFundAccountV2DTO.setOperator(manageChangeFundDTO.getOperator());
        changeFundAccountV2DTO.setManualFlag(true);
        changeFundAccountV2DTO.setOrderNo(orderNo);

        fundService.subtract(changeFundAccountV2DTO);

        return result;
    }

    @Override
    public Result manageReversalFund(ManageChangeFundDTO manageChangeFundDTO) {

        if (commonService.repeatSubmit(manageChangeFundDTO.getUserPhone() + ":manageSubtractFund")) {
            return Result.builder().fail(BizCodeMessages.CORE_API_REQUEST_LIMITED);
        }

        UserBaseExample userBaseExample = new UserBaseExample();
        userBaseExample.createCriteria().andPlatNoEqualTo(manageChangeFundDTO.getPlatNo()).andPhoneEqualTo(manageChangeFundDTO.getUserPhone());
        List<UserBase> userBases = userBaseMapper.selectByExample(userBaseExample);
        if (CollectionUtils.isEmpty(userBases)) {
            return Result.builder().fail(BizCodeMessages.PARAMETER_ERR, "用户不存在");
        }

        AccountType fromAccountType = AccountType.getAccountTypeByFullCode(manageChangeFundDTO.getAccountType());
        AccountMainJournalType accountMainJournalType = AccountMainJournalType.getMainJournalTypeByCode(manageChangeFundDTO.getAccountMainJournalType());

        JournalInfoVO journalVO = ChangeTypeConstant.getReversalJournalType(fromAccountType,
                accountMainJournalType);

        FundBillType fundBillType = FundBillType.getUserBillType(manageChangeFundDTO.getBillType());
        String orderNo = WithdrawAccountConfig.genOrderNo(OrderNoPrefixEnum.MANAGE_REVERSAL.getCode());

        ChangeFundAccountV2DTO changeFundAccountV2DTO = new ChangeFundAccountV2DTO();
        changeFundAccountV2DTO.setUserBaseId(userBases.get(0).getUserBaseId());
        changeFundAccountV2DTO.setFundBillType(fundBillType);
        changeFundAccountV2DTO.setChangeAmount(manageChangeFundDTO.getChangeAmount());
        changeFundAccountV2DTO.setChannelId(ChannelIdEnums.no.getCode());
        changeFundAccountV2DTO.setPlatNo(manageChangeFundDTO.getPlatNo());
        changeFundAccountV2DTO.setDetail(manageChangeFundDTO.getDetail());
        changeFundAccountV2DTO.setJournalInfo(journalVO);
        changeFundAccountV2DTO.setOperator(manageChangeFundDTO.getOperator());
        changeFundAccountV2DTO.setManualFlag(true);
        changeFundAccountV2DTO.setOrderNo(orderNo);

        return fundService.reversal(changeFundAccountV2DTO);

    }

    @Override
    public Result addWithdrawalDebitList(ManageAddWithdrawalDebitDTO dto) {

        KLog.info("添加提现负债记录入参:{}", dto.toString());
        UserBaseExample userBaseExample = new UserBaseExample();
        userBaseExample.createCriteria()
                .andReferralCodeEqualTo(dto.getReferralCode())
                .andUserNameEqualTo(dto.getUserName())
                .andPlatNoEqualTo(dto.getPlatNo())
                .andIsDelNotEqualTo(DeleteFlag.TRUE);
        List<UserBase> userBaseList = userBaseMapper.selectByExample(userBaseExample);
        if (CollectionUtils.isEmpty(userBaseList)) {
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "未找到用户，请确认信息是否输入正确！");
        }

        UserBase userBase = userBaseList.get(0);
        LocalDateTime now = LocalDateTime.now();
        //加入
        FundWithdrawDebitList insertFundWithdrawDebitList = new FundWithdrawDebitList();
        insertFundWithdrawDebitList.setUserBaseId(userBase.getUserBaseId());
        insertFundWithdrawDebitList.setSubtractAmount(dto.getSubtractAmount());
        insertFundWithdrawDebitList.setStatus(FundWithdrawDebitListEnum.DebitStatusEnum.STATUS_100.getCode());
        insertFundWithdrawDebitList.setPlatNo(dto.getPlatNo());
        insertFundWithdrawDebitList.setAddReason(dto.getAddReason());
        insertFundWithdrawDebitList.setCreateTime(now);
        insertFundWithdrawDebitList.setUpdateTime(now);
        insertFundWithdrawDebitList.setAddOperator(dto.getOperator());
        fundWithdrawDebitListMapper.insertSelective(insertFundWithdrawDebitList);
        return Result.builder().success();
    }

    @Override
    public Result withdrawalDebitList(ManageWithdrawalDebitListDTO dto) {

        KLog.info("查询提现负债记录入参:{}", dto.toString());

        if (Objects.nonNull(dto.getPlatNo()) && !PlatNoEnums.YXY.isEquals(dto.getPlatNo()) && !PlatNoEnums.KLKS.isEquals(dto.getPlatNo())) {
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "暂不支持的平台类型");
        }
        if (StringUtils.isBlank(dto.getPhone())) {

            if (StringUtils.isAllBlank(dto.getCreateTimeBegin(), dto.getCreateTimeEnd(), dto.getRemoveTimeBegin(),
                    dto.getRemoveTimeEnd())) {
                return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "无用户信息查询时间不能超过90天");
            }

            if (StringUtils.isNotBlank(dto.getCreateTimeBegin())) {
                Duration durationCreateTime = Duration.between(LocalDate.parse(dto.getCreateTimeBegin(), DateTimeFormatter.ISO_DATE).atStartOfDay(),
                        LocalDate.parse(dto.getCreateTimeEnd(), DateTimeFormatter.ISO_DATE).atStartOfDay());
                if (durationCreateTime.toDays() > 90) {
                    return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "无用户信息查询时间不能超过90天");
                }
            }

            if (StringUtils.isNotBlank(dto.getRemoveTimeBegin())) {
                Duration durationRemoveTime = Duration.between(LocalDate.parse(dto.getRemoveTimeBegin(), DateTimeFormatter.ISO_DATE).atStartOfDay(),
                        LocalDate.parse(dto.getRemoveTimeEnd(), DateTimeFormatter.ISO_DATE).atStartOfDay());
                if (durationRemoveTime.toDays() > 90) {
                    return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "无用户信息查询时间不能超过90天");
                }
            }

        }

        //查当天
        if (StringUtils.isNotBlank(dto.getCreateTimeEnd())) {
            dto.setCreateTimeEnd(LocalDate.parse(dto.getCreateTimeEnd(), DateTimeFormatter.ISO_DATE).plusDays(1).format(DateTimeFormatter.ISO_DATE));
        }
        if (StringUtils.isNotBlank(dto.getRemoveTimeEnd())) {
            dto.setRemoveTimeEnd(LocalDate.parse(dto.getRemoveTimeEnd(), DateTimeFormatter.ISO_DATE).plusDays(1).format(DateTimeFormatter.ISO_DATE));
        }

        PageFrom.startPage(dto.getPageNum(), dto.getPageSize());
        List<ManageWithdrawalDebitListVO> manageWithdrawalDebitListVOList = transactionFundWithdrawDebitListMapper.withdrawalDebitList(dto);
        if (CollectionUtils.isEmpty(manageWithdrawalDebitListVOList)) {
            return Result.builder().successPage(manageWithdrawalDebitListVOList);
        }

        manageWithdrawalDebitListVOList.forEach(manageWithdrawalDebitListVO -> {
                    manageWithdrawalDebitListVO.setStatusName(FundWithdrawDebitListEnum.DebitStatusEnum.getMsgByCode(manageWithdrawalDebitListVO.getStatus()));
                    if (StringUtil.equals(manageWithdrawalDebitListVO.getPlatNo(), PlatNoEnums.KLKS.getCode() + "")) {
                        manageWithdrawalDebitListVO.setPlatNo("快收");
                    } else {
                        manageWithdrawalDebitListVO.setPlatNo(PlatNoEnums.getPlatNo(Short.parseShort(manageWithdrawalDebitListVO.getPlatNo())).getName());
                    }
                }
        );

        return Result.builder().successPage(manageWithdrawalDebitListVOList);
    }

    @Override
    public Result removeWithdrawalDebitList(ManageRemoveWithdrawalDebitListDTO dto) {

        KLog.info("解除提现负债名单入参:{}", dto.toString());
        FundWithdrawDebitList fundWithdrawDebitList =
                fundWithdrawDebitListMapper.selectByPrimaryKey(dto.getFundWithdrawDebitListId());
        if (Objects.isNull(fundWithdrawDebitList)) {
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "查询负债记录失败，请确认信息是否输入正确！");
        }
        if (!FundWithdrawDebitListEnum.DebitStatusEnum.STATUS_100.getCode().equals(fundWithdrawDebitList.getStatus())) {
            return Result.builder().success();
        }

        LocalDateTime removeTime = LocalDateTime.now();
        FundWithdrawDebitList upFundWithdrawDebitList = new FundWithdrawDebitList();
        upFundWithdrawDebitList.setFundWithdrawDebitListId(dto.getFundWithdrawDebitListId());
        upFundWithdrawDebitList.setRemoveOperator(dto.getOperator());
        upFundWithdrawDebitList.setRemoveReason(dto.getRemark());
        upFundWithdrawDebitList.setRemoveTime(removeTime);
        //取消（不扣款）
        if (FundWithdrawDebitListEnum.DebitStatusEnum.STATUS_300.getCode().equals(dto.getStatus())) {

            try {
                changeBusinessStatus(fundWithdrawDebitList, dto.getRemark());
            } catch (Exception e) {
                KLog.error("解除提现负债名单更改业务状态异常，入参：{}，堆栈：{}", dto, e);
                return Result.builder().fail(BizCodeMessages.UNKNOWN_ERROR, e.getMessage());
            }
            upFundWithdrawDebitList.setStatus(FundWithdrawDebitListEnum.DebitStatusEnum.STATUS_300.getCode());
            fundWithdrawDebitListMapper.updateByPrimaryKeySelective(upFundWithdrawDebitList);
            return Result.builder().success();
        }

        List<FundAccount> fundAccountList = new ArrayList<>();

        if (BigDecimal.ZERO.compareTo(fundWithdrawDebitList.getSubtractAmount()) < 0) {
            //校验金额
            FundAccountExample fundAccountExample = new FundAccountExample();
            FundAccountExample.Criteria criteria = fundAccountExample.createCriteria();
            criteria.andUserBaseIdEqualTo(fundWithdrawDebitList.getUserBaseId()).andIsDelNotEqualTo(DeleteFlag.TRUE);
            if (PlatNoEnums.YXY.isEquals(fundWithdrawDebitList.getPlatNo())) {
                criteria.andAccountTypeEqualTo(AccountType.getFullCode(AccountType.ALLY_V2, PlatNoEnums.YXY.getCode()));
            }
            fundAccountList = fundAccountMapper.selectByExample(fundAccountExample);
            if (CollectionUtils.isEmpty(fundAccountList)) {
                return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "用户账户余额不足，不支持移除负债名单！");
            }

            BigDecimal withdrawableAmount = BigDecimal.ZERO;
            for (FundAccount fundAccount : fundAccountList) {
                withdrawableAmount = withdrawableAmount.add(fundAccount.getAccountAmountWithdrawable());
            }

            if (withdrawableAmount.compareTo(fundWithdrawDebitList.getSubtractAmount()) < 0) {
                return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "用户账户余额不足，不支持移除负债名单！");
            }
            //减账
            try {
                subFundAmount(fundAccountList, fundWithdrawDebitList, dto);
            } catch (Exception e) {
                return Result.builder().fail(BizCodeMessages.TRANSACTION_SUBTRACT_ACCOUNT_FAIL, "减账异常，堆栈：{}", e);
            }
        }

        if (StringUtils.isNotBlank(fundWithdrawDebitList.getBusinessId())) {

            try {
                changeBusinessStatus(fundWithdrawDebitList, dto.getRemark());
            } catch (Exception e) {
                KLog.error("解除提现负债名单更改业务状态异常，入参：{}，堆栈：{}", dto, e);
                return Result.builder().fail(BizCodeMessages.UNKNOWN_ERROR, e.getMessage());
            }

        }

        upFundWithdrawDebitList.setStatus(FundWithdrawDebitListEnum.DebitStatusEnum.STATUS_200.getCode());
        fundWithdrawDebitListMapper.updateByPrimaryKeySelective(upFundWithdrawDebitList);
        return Result.builder().success();

    }

    /**
     * 扣掉负债金额
     *
     * @param fundAccountList
     * @param fundWithdrawDebitList
     * @param dto
     */
    private void subFundAmount(List<FundAccount> fundAccountList,
                               FundWithdrawDebitList fundWithdrawDebitList,
                               ManageRemoveWithdrawalDebitListDTO dto) {

        throw new SysBizException(BizCodeMessages.UNKNOWN_ERROR, "接口已废弃");
    }

    /**
     * 更改业务状态
     *
     * @param fundWithdrawDebitList
     * @param remark
     */
    private void changeBusinessStatus(FundWithdrawDebitList fundWithdrawDebitList, String remark) {

        if (FundWithdrawDebitListEnum.BusinessTypeEnum.ALLOWANCE.getCode().equals(fundWithdrawDebitList.getBusinessType())) {

            AllyAwardBill allyAwardBill =
                    allyAwardBillMapper.selectByPrimaryKey(fundWithdrawDebitList.getBusinessId());

            if (!SubTeamBeanEnum.PaymentStatusEnum.isWaitPay(allyAwardBill.getPaymentStatus())) {
                throw new BizRuntimeException(BizCodeMessages.VALIDATOR_ERR, "管理津贴发放状态错误");
            }

            AllyAwardBill upAllyAwardBill = new AllyAwardBill();
            upAllyAwardBill.setAllyAwardBillId(allyAwardBill.getAllyAwardBillId());
            upAllyAwardBill.setRemark(remark);
            LocalDateTime paymentTime = LocalDateTime.now();
            upAllyAwardBill.setPaymentTime(paymentTime);
            upAllyAwardBill.setPaymentStatus(SubTeamBeanEnum.PaymentStatusEnum.PAYMENT_STATUS_40.getCode());

            allyAwardBillMapper.updateByPrimaryKeySelective(upAllyAwardBill);
        } else if (StringUtils.isNotEmpty(fundWithdrawDebitList.getBusinessType())) {
            throw new BizRuntimeException(BizCodeMessages.VALIDATOR_ERR, "暂不支持的业务类型");
        }

    }
}
